import {Server} from '@/stores/ajax';
import {QuillDeltaToHtmlConverter} from 'quill-delta-to-html';
import {Delta, QuillEditor} from '@vueup/vue-quill'
import {GetUserState} from '@/stores/userState';
import {nextTick, ref} from 'vue'

type Posts = {
    total: number,
    list: any[]
} | null

export class ServerUtils {
    static getQuillHTML = (editor: any) => {
        return new QuillDeltaToHtmlConverter(editor.getContents().ops, {}).convert()
    }
    static checkQuillWordsNum(editor: any, minWordsLength: number, maxWordsLength: number): boolean {
        if (editor.getText().replace(/(\n[\s\t]*\r*\n)/g, '\n').length - 1 < minWordsLength) {
            Server.showMessage(`字数少于${minWordsLength}！`)
            return false
        }
        if (editor.getText().length > maxWordsLength) {
            Server.showMessage(`字数大于${maxWordsLength}！！`)
            return false
        }
        return true
    }
    static post = async (editor: any, subarea: number, title: string | null, minWordsLength = 5, maxWordsLength = 9000, thumbnail: null | string = null) => {
        if (!ServerUtils.checkQuillWordsNum(editor, minWordsLength, maxWordsLength)) return
        let _res = null
        await Server.post('/post/post', {
            subarea, title, thumbnail,
            content: ServerUtils.getQuillHTML(editor)
        }, true).then(res => {
            if (res.data && res.data.code == 0) {
                editor.setContents(new Delta())
                _res = res.data.return
            }
        })

        return _res
    }

    static comment = async (editor: any, pid: number, minWordsLength = 5, maxWordsLength = 1000) => {
        if (!ServerUtils.checkQuillWordsNum(editor, minWordsLength, maxWordsLength)) return
        await Server.post('/post/comment', {
            pid,
            content: ServerUtils.getQuillHTML(editor)
        }, true).then(res => {
            if (res.data && res.data.code == 0) {
                editor.setContents(new Delta())
                return res
            }
        })
        return null
    }
    static sendMessage = async (editor: any, uid: number, minWordsLength = 5, maxWordsLength = 1000) => {
        if (!ServerUtils.checkQuillWordsNum(editor, minWordsLength, maxWordsLength)) return false
        await Server.post('/notification/send_message', {
            uid, content: ServerUtils.getQuillHTML(editor)
        }, true).then(res => {
            if (res.data && res.data.code == 0) {
                editor.setContents(new Delta())
                return res
            }
        })
        return null
    }
    static collect = async (post: any) => {
        await ServerUtils.changeRelationship(post, 'collect')
    }
    static star = async (post: any) => {
        await ServerUtils.changeRelationship(post, 'star')
    }
    static changeRelationship = async (post: any, relationship: string) => {
        // console.log(post[relationship])
        let user = GetUserState()
        let flag = !post[relationship].includes(user.uid + '')
        await Server.get('/post/change_relationship', {
            pid: post.pid, relationship, value: flag
        }, true)
        if (!flag) {
            post[relationship] = post[relationship].filter((item: string) => item != String(user.uid))
            if (post[relationship + '_count'] != undefined) {
                post[relationship + '_count']--
            }
        } else {
            post[relationship].push(String(user.uid))
            if (post[relationship + '_count'] != undefined) {
                post[relationship + '_count']++
            }
        }
    }
    static async changeUserRelative(uid: number, relationship: string, value: boolean) {

        await Server.get('/user/change_user_relative', {
            uid, relationship, value
        }, true).then(res => {

        })
    }
    // TODO 改成传入对象
    static async getPosts(subarea: number | null, pid: number | null, author: number | null, relationships: string[], paged: number, posts_per_page: number, onlyTopic = false, key: string | null = null): Promise<Posts> {
        let posts: Posts = null
        await Server.get('/post/get_posts', {
            subarea, pid, relationships, paged, posts_per_page, author, onlyTopic: onlyTopic ? 1 : 0, key
        }).then(res => {
            if (res.data && res.data.code == 0) {
                posts = res.data.return
                if (posts?.list.length) {
                    for (let post of posts.list as any) {

                    }
                }
            }
        })
        return posts
    }
    static async getSubarea(subareaid: number) {
        let subarea: any = null
        await Server.get('/post/get_subarea', {
            subareaid
        }).then(res => {
            if (res.data && res.data.code == 0) {
                subarea = res.data.return
            }
        })
        return subarea
    }
    static async getSubareas(type: number, paged: number, posts_per_page: number) {
        let subareas: any[] = []
        await Server.get('/post/get_subareas', {
            type, paged, posts_per_page
        }).then(res => {
            if (res.data && res.data.code == 0) {
                subareas = res.data.return
            }
        })
        return subareas
    }
    static async getTopics(relationships: string[],type:number, subarea: number, sortby: string, paged: number, posts_per_page: number): Promise<Posts> {
        let posts: Posts = null
        await Server.get('/post/get_topics', {
            relationships, paged, posts_per_page, subarea, sortby,type
        }).then(res => {
            console.log(res);
            
            if (res.data && res.data.code == 0) {
                posts = res.data.return
                if (posts?.list.length) {
                    for (let post of posts.list as any) {

                    }
                }
            }
        })
        return posts
    }
    static async getSubPostsList(ppid: number, sortby = 'create_time'): Promise<any> {
        let _res: any = null

        await Server.get('/post/get_sub_posts', {
            ppid, sortby, onlyPid: 1
        }).then(res => {
            if (res.data && res.data.code == 0) {
                _res = res.data.return
            }
        })
        return _res
    }
    static async getSubPosts(ppid: number | null, relationships: string[], paged: number, posts_per_page: number, onlyAuthor = false, tid: number | null = null, sortby: string | null = null, direction: string | null = null): Promise<any> {
        let _res: any = null

        await Server.get('/post/get_sub_posts', {
            ppid, relationships, paged, posts_per_page, onlyAuthor: onlyAuthor ? 1 : 0, sortby, direction, tid
        }).then(res => {
            if (res.data && res.data.code == 0) {
                _res = res.data.return
                let posts = _res.subPosts
                if (posts?.list.length) {
                    for (let post of posts.list) {

                    }
                }
            }
        })
        return _res
    }
    static async getTopicPosts(tid: number, relationships: string[], onlyAuthor: boolean, paged: number, posts_per_page: number): Promise<any> {
        let topicPosts: any = null

        await Server.get('/post/get_topic_posts', {
            tid, relationships, paged, posts_per_page, onlyAuthor: Number(onlyAuthor)
        }).then(res => {
            if (res.data && res.data.code == 0) {
                topicPosts = res.data.return
                let post = topicPosts.post
                topicPosts.topic.post = post
            }
        })
        return topicPosts
    }
    static async getUserDataById(uid: number, details = false) {
        let user: any = null
        await Server.get('/user/get_user_data', {
            userId: uid, details: Number(details)
        }).then(res => {
            if (res.data && res.data.code == 0) {
                user = res.data.return
            }
        })
        return user
    }
    static async getPostByRelationship(uid: number, paged: number, posts_per_page: number, relationships: Array<String>, byRelationship: string = '', subarea: number = 0,) {
        let user: any = null
        await Server.get('/post/get_posts_by_relationship', {
            uid, paged, posts_per_page, subarea: subarea ? subarea : undefined,
            byRelationship: byRelationship || undefined, relationships
        }).then(res => {
            if (res.data && res.data.code == 0) {
                user = res.data.return
            }
        })
        return user
    }
    static async getNotification(paged: number, notifications_per_page: number, type: string = '') {
        let notifications: any = null
        await Server.get('/notification/get', {
            paged, notifications_per_page, type: type ? type : undefined
        }).then(res => {
            if (res.data && res.data.code == 0) {
                notifications = res.data.return

                for (let n of notifications.list) {
                    n.content = this.translate(n)
                }
            }
        })
        return notifications
    }

    static translate(notification: Notification) {
        let note: string = (window as any).notificationConfig[notification.type]
        note = note.replaceAll(/#\{([\s\S]*?)\}/g, (substring: string, ...args: any[]) => {
            let str = args[0].split(':')
            let type: string = str[0].trim()
            let value: string = str[1].trim()
            let res: string = (notification as any)[value]
            return res
        })
        return note
    }
    static uploadImage = async (data: any) => {
        let url = null
        await Server.axios.post("/file/upload_image", {image: data}, {
            headers: {
                'Content-Type': 'multipart/form-data'
            }
        }).then((res) => {
            Server.checkShowMessage(res)
            if (res.data && res.data.code == 0) {
                url = res.data.return
            }
        })
        return url
    }
}
interface Notification {
    id: number
    type: string
    p1: string
    p2: string
    p3: string
    time: Date
    has_read: Boolean
}

